package features.advance.leetcode.interview.alibaba;

import java.sql.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 *  4、线程异步执行求和提取执行结果
 *  将下面代码示例中的sum()方法调用改成异步调用,
 *  并获取执行结果。写出2种实现方式。(注:要保存或者提取执行结果不是单单输出)
 *
 * @author LIN
 * @date 2021-08-16
 */
public class Async {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // Object类的加载原理
        new Object();
        Connection connection = null;
        try {
             connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/erpcg_pd?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8");
            Statement statement = connection.createStatement();
            ResultSet execute = statement.executeQuery("select * from erpcg_pd.pdccocartype");
            while (execute.next()){
                int companycode = execute.findColumn("companycode");
                String string = execute.getString(companycode);

                System.out.println(string);

            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

        }


        long start = System.currentTimeMillis();

        // 在这里创建一个线程或线程池
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return sum();
            }
        };
        // 异步执行下面的方法 TODO
//        int result = sum();
        FutureTask<Integer> task = new FutureTask<>(callable);
        FutureTask<Integer> task1 = new FutureTask<>(callable);
        FutureTask<Integer> task2 = new FutureTask<>(callable);
        Thread thread = new Thread(task);
        Thread thread1 = new Thread(task1);
        Thread thread2 = new Thread(task2);
        thread.start();
        thread1.start();
        thread2.start();
        int result = task.get();

        // 确保拿到result并输出
        System.out.println("异步计算结果为："+result);
        result = task1.get();
        System.out.println("异步计算结果为："+result);
        result = task2.get();
        System.out.println("异步计算结果为："+result);


        System.out.println("使用时间："+(System.currentTimeMillis()-start)+" ms");
        // 然后退出main线程
    }
    private static int sum(){
        return fibo(20);
    }

    private static int fibo(int a) {
        if(a<2){
            return 1;
        }
        return fibo(a-1) + fibo(a-2);
    }
}
